package com.ryan.ohos.extension.util;

import ohos.agp.utils.Color;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

/**
 * 颜色工具类
 */
public final class ColorUtil {

    private static final int DEFAULT_FF0000 = 0xff0000;
    private static final int DEFAULT_00FF00 = 0x00ff00;
    private static final int DEFAULT_0000FF = 0x0000ff;

    private static final int ONE = -1;
    private static final int SECOND = 2;
    private static final int THIRD = 3;
    private static final int FOUR = 4;
    private static final int NUMBER8 = 8;
    private static final int NUMBER16 = 16;
    private static final int ADJUST = 24;
    private static final int SIXTEN = 60;
    private static final int ONE_SECOND = 120;
    private static final int SECOND_FOUR = 240;
    private static final int ALPHA_INT = 255;
    private static final int THIRD_SIX = 360;

    private static final int LOG_ID = 0x000115;
    private static final float ALPHA = 255f;
    private static final int ADJUST_COLOR = 0x00ffffff;
    private static final int WHITE = 0xFFFFFFFF;
    private static final int WHITE2 = 0xFFFFFF;

    private static HiLogLabel logLabel = new HiLogLabel(HiLog.LOG_APP, LOG_ID, "ColorUtil");

    /**
     * 透明度数值
     *
     * @param argb 色值
     * @return 透明度数值
     */
    public static float getAlphaPercent(int argb) {
        return Color.alpha(argb) / ALPHA;
    }

    /**
     * 透明度数值
     *
     * @param alpha
     * @return 透明度数值
     */
    public static int alphaValueAsInt(float alpha) {
        return Math.round(alpha * ALPHA_INT);
    }

    /**
     * 透明度调整
     *
     * @param alpha
     * @param color
     * @return 透明度数值
     */
    public static int adjustAlpha(float alpha, int color) {
        return alphaValueAsInt(alpha) << ADJUST | (ADJUST_COLOR & color);
    }

    /**
     * 颜色和亮度
     *
     * @param color
     * @param lightness
     * @return colorAtLightness
     */
    public static int colorAtLightness(int color, float lightness) {
        float[] hsv = new float[THIRD];
        int red = (color & DEFAULT_FF0000) >> NUMBER16;
        int green = (color & DEFAULT_00FF00) >> NUMBER8;
        int blue = color & DEFAULT_0000FF;
        double[] hsvColor = rgbToHsv(red, green, blue);
        hsv[0] = (float) hsvColor[0];
        hsv[1] = (float) hsvColor[1];
        hsv[SECOND] = (float) hsvColor[SECOND];
        hsv[SECOND] = lightness;
        float[] rgbColor = hsvToRgb(hsv);
        int colorInit = Color.rgb((int) rgbColor[0], (int) rgbColor[1], (int) rgbColor[SECOND]);
        return colorInit;
    }

    /**
     * 获取颜色亮度数值
     *
     * @param color
     * @return 获取颜色亮度数值
     */
    public static float lightnessOfColor(int color) {
        int red = (color & DEFAULT_FF0000) >> NUMBER16;
        int green = (color & DEFAULT_00FF00) >> NUMBER8;
        int blue = color & DEFAULT_0000FF;
        double[] hsvColor = rgbToHsv(red, green, blue);
        return (float) hsvColor[SECOND];
    }

    /**
     * Color和Alpha转Hex
     *
     * @param color
     * @param isShowAlpha
     * @return 颜色id和透明度转Hex格式
     */
    public static String isHexString(int color, boolean isShowAlpha) {
        int isBase = isShowAlpha ? WHITE : WHITE2;
        String format = isShowAlpha ? "#%08X" : "#%06X";
        return String.format(format, isBase & color);
    }

    /**
     * HSV转RGB
     *
     * @param hsb
     * @return RGB
     */
    public static float[] hsvToRgb(float[] hsb) {
        float[] rgb = new float[THIRD];

        // 先令饱和度和亮度为100%，调节色相h
        for (int offset = SECOND_FOUR, inum = 0; inum < THIRD; inum++, offset -= ONE_SECOND) {
            // 算出色相h的值和三个区域中心点(即0°，120°和240°)相差多少，然后根据坐标图按分段函数算出rgb。
            // 但因为色环展开后，红色区域的中心点是0°同时也是360°，不好算，索性将三个区域的中心点都向右平移到240°再计算比较方便
            float xx = Math.abs((hsb[0] + offset) % THIRD_SIX - SECOND_FOUR);

            // 如果相差小于60°则为255
            if (xx <= SIXTEN) {
                rgb[inum] = ALPHA_INT;
            }

            // 如果相差在60°和120°之间，
            else if (xx > SIXTEN && xx < ONE_SECOND) {
                rgb[inum] = (1 - (xx - SIXTEN) / SIXTEN) * ALPHA_INT;
            }

            // 如果相差大于120°则为0
            else {
                rgb[inum] = 0;
            }
        }

        // 再调节饱和度s
        for (int ii = 0; ii < THIRD; ii++) {
            rgb[ii] += (ALPHA_INT - rgb[ii]) * (1 - hsb[1]);
        }

        // 最后调节亮度b
        for (int ii = 0; ii < THIRD; ii++) {
            rgb[ii] *= hsb[SECOND];
        }
        return rgb;
    }

    /**
     * RGB转HSV
     *
     * @param rr
     * @param gg
     * @param bb
     * @return HSV
     */
    public static double[] rgbToHsv(double rr, double gg, double bb) {
        double hh;
        double ss;
        double vv;
        double min;
        double max;
        min = Math.min(Math.min(rr, gg), bb);
        max = Math.max(Math.max(rr, gg), bb);
        double delta;
        vv = max;
        delta = max - min;
        if (max != 0) {
            ss = delta / max;
        } else {
            ss = 0;
            hh = ONE;
            return new double[]{hh, ss, vv};
        }

        if (rr == max) {
            // 黄色和红色之间
            hh = (gg - bb) / delta;
        } else if (gg == max) {
            // 绿色和黄色之间
            hh = SECOND + (bb - rr) / delta;
        } else {
            // 黄色和了白色之间
            hh = FOUR + (rr - gg) / delta;
        }

        // degrees
        hh *= SIXTEN;
        if (hh < 0) {
            hh += THIRD_SIX;
        }

        return new double[]{hh, ss, vv};
    }

    /**
     * Hex转RGB
     *
     * @param hex
     * @return RGB
     */
    public static int[] hexToRgb(String hex) {
        int color = Integer.parseInt(hex.replace("#", ""), NUMBER16);
        int red = (color & DEFAULT_FF0000) >> NUMBER16;
        int green = (color & DEFAULT_00FF00) >> NUMBER8;
        int blue = color & DEFAULT_0000FF;
        return new int[]{red, green, blue};
    }

    /**
     * Hex转Color
     *
     * @param hex
     * @return Color
     */
    public static int hexToColor(String hex) {
        int color = Integer.parseInt(hex.replace("#", ""), NUMBER16);
        return color;
    }

    /**
     * color转Hex
     *
     * @param color
     * @return 颜色id转Hex格式
     */
    public static String getHexString(int color) {
        String her = Integer.toHexString(color);
        return her;
    }

    /**
     * Color转RGB
     *
     * @param color
     * @return RGB
     */
    public static int[] colorToRgb(int color) {
        int red = (color & DEFAULT_FF0000) >> NUMBER16;
        int green = (color & DEFAULT_00FF00) >> NUMBER8;
        int blue = color & DEFAULT_0000FF;
        return new int[]{red, green, blue};
    }

}